import Cocoa
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

//var str = "Hello, playground"


/**
 GCD队列:
 1. 主队列: 任务在主线程执行
 2. 并行队列: 任务会以先进先出的顺序入列和出列. 但是因为多个任务可以并行执行. 所以完成顺序是不一定的
 3. 串行队列: 任务会以先进先出的顺序入列和出列, 但是同一个时刻只会执行一个任务
 
 4. 最终的目标队列都是主队列和全局队列
 5. 如果把一个并行队列的目标队列设置为一个串行队列, 那么并行队列将不再并行
 6. 如果多个队列的目标队列都设置为同一个串行队列, 那么这多个队列连同目标队列里的任务都将串行执行
 7. 如果设置目标队列形成环了,结果是不可预期的
 8. 如果一个队列正在执行任务的时候更换目标队列, 结果也是不可预期的
 */

/**
 GCD的基本操作:
 1. sync: 提交任务到当前队列里,并且直到任务执行完成,当前队列才会返回
 2. async: 调度一个任务去立即执行, 但是不用等任务执行完,当前队列就会返回
 3. asyncAfter: 调度一个任务去多久之后执行, 但是不用等任务执行完成,当前队列就会返回
 */

// qos:队列的服务质量 (default,  background, userInitiated)
//attributes: 队列的属性
// autoreleaseFrequency: 自动释放的频次
// concurrent: 并行队列
// inherit: 继承, 接手, 承担
//let queue = DispatchQueue(label: "myQueue", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit, target: nil)
//queue.sync {   //同步执行操作
//    sleep(1)
//    print("in queue sync")
//    print("current is \(Thread.current)")
//}
//queue.async {  //异步执行操作
//    sleep(1)
//    print("in queue async")
//    print("current is \(Thread.current)")
//}
//print("after invoke queue method")

//使用asyncAfter
//DispatchTime(系统时钟,如果此时系统崩溃了,这个时间是不会走的) 和 DispatchWallTime(生活时间,墙上的时间,如果系统崩溃了, 这个时间和现实时间一样还是在走)

//queue.asyncAfter(deadline: .now() + 1) {  //1秒后执行内部的操作
//    print("in asyncAfter")
//}
//print("after invoke queue method")


/**
 GCD的高级特性:
 1. 调度组: DispatchGroup
 2. DispatchSource:
 */

//调度组()
//let group = DispatchGroup()
//let queue2 = DispatchQueue(label: "request_queue", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent)
//print("current is \(Thread.current)")
////需要注意的是enter和leave方法必须要成对出现
//group.enter()
//queue2.async {
//    sleep(1)
//    print("接口 A 数据请求完成")
//    group.leave()
//}
//
//group.enter()
//queue2.async {
//    sleep(1)
//    print("接口 B 数据请求完成")
//    group.leave()
//}
//print("group enter 执行完毕")
////DispatchGroup-wait:可以等前面的group中的操作都执行完成,但是会阻塞线程
////group.wait()
////DispatchGroup-notify:可以等前面的group中的操作都执行完成,但是不会阻塞线程,会继续执行后面的代码
//group.notify(queue: queue2) {
//    print("接口 A 和接口 B 的数据请求都已经完毕, 开始合并两个接口的数据")
//}
//print("验证不堵塞!!")

//DispatchSource: 简单来说，dispatch source是一个监视某些类型事件的对象。当这些事件发生时，它自动将一 个 task 放入一个dispatch queue的执行例程中。
//DispatchSource-Timer
var seconds = 10
let timer: DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global())
timer.schedule(deadline: .now(), repeating: 1.0)  //每隔1秒后重复一次定时器中的代码
timer.setEventHandler {
    seconds -= 1
    if seconds < 0 {
        timer.cancel()
    } else {
        print(seconds)
    }
}
//resume: 继续,重新开始
timer.resume()



